﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DLog.Common
{
    public class NotepadHelper
    {
        /// <summary>
        /// if the directory of the file path is not exsit,function will create the directory 
        /// </summary>
        public static void CreateLogFile(string filePath)
        {
            string directoryPath = filePath.Substring(0, filePath.LastIndexOf('\\'));
            if (!Directory.Exists(directoryPath))
            {
                try
                {
                    Directory.CreateDirectory(directoryPath);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            if (!File.Exists(filePath))
            {
                try
                {
                    FileStream file = File.Create(filePath);
                    file.Dispose();
                    file.Close();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }

        #region write log into notepad file

        /// <summary>
        ///write log into the file of path
        /// </summary>
        /// <param name="logText"></param>
        public static void LogWrite(string logText, string filePath)
        {
            CreateLogFile(filePath);
            StreamWriter sw = new StreamWriter(filePath, true, System.Text.Encoding.UTF8);
            try
            {
                sw.WriteLine(logText);
                sw.Flush();
            }
            finally
            {
                sw.Dispose();
                sw.Close();
            }
        }

        /// <summary>
        ///write log into the file of path
        /// </summary>
        /// <param name="logText"></param>
        public static void LogWrite(Dictionary<string, string> log, string filePath)
        {
            LogWrite(log, ':', filePath);
        }

        /// <summary>
        ///write log into the file of path
        /// </summary>
        /// <param name="logText"></param>
        public static void LogWrite(Dictionary<string, string> log, char splitStr, string filePath)
        {
            CreateLogFile(filePath);
            StreamWriter sw = new StreamWriter(filePath, true, System.Text.Encoding.UTF8);
            try
            {
                for (int i = 0; i < log.Count; i++)
                {
                    sw.WriteLine(log.ElementAt(i).Key + splitStr + log.ElementAt(i).Value);
                }
                sw.Flush();
            }
            finally
            {
                sw.Dispose();
                sw.Close();
            }
        }

        /// <summary>
        /// write log into the file of path
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="filePath"></param>
        public static void LogWrite(string logKey, string logValue, string filePath)
        {
            LogWrite(logKey, ':', logValue, filePath);
        }

        /// <summary>
        /// write log into the file of path
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="filePath"></param>
        public static void LogWrite(string logKey, char splitStr, string logValue, string filePath)
        {
            CreateLogFile(filePath);
            StreamWriter sw = new StreamWriter(filePath, true, System.Text.Encoding.UTF8);
            try
            {
                sw.WriteLine(logKey + splitStr + logValue);
                sw.Flush();
            }
            finally
            {
                sw.Dispose();
                sw.Close();
            }
        }

        /// <summary>
        /// write log into the file of path
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="filePath"></param>
        public static void LogWrite(Exception ex, string filePath)
        {
            CreateLogFile(filePath);
            StreamWriter sw = new StreamWriter(filePath, true, System.Text.Encoding.UTF8);
            try
            {
                sw.WriteLine("/********************************/");
                sw.WriteLine("DateTime：" + System.DateTime.Now.ToString());
                sw.WriteLine();
                sw.WriteLine("Source：" + ex.Source);
                sw.WriteLine("Message：" + ex.Message);
                sw.WriteLine("/********************************/");
                sw.WriteLine();
                sw.WriteLine();
                sw.Flush();
            }
            finally
            {
                sw.Dispose();
                sw.Close();
            }
        }

        #endregion

        #region read log from notepad file

        public static List<string> LogRead(string filePath)
        {
            return LogRead(null, null, null, null, null, filePath);
        }

        public static List<string> LogRead(string condition, string filePath)
        {
            return LogRead(condition, null, null, null, null, filePath);
        }

        public static List<string> LogRead(string DateFieldName, string splitStr, DateTime startDate, DateTime endDate, string filePath)
        {
            return LogRead(null, DateFieldName, splitStr, startDate, endDate, filePath);
        }
        /// <summary>
        ///  read notepad file log message
        /// </summary>
        /// <param name="condition">log message condition</param>
        /// <param name="DateFieldName">help to obtain this field value</param>
        /// <param name="splitStr">help to obtain this field value</param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static List<string> LogRead(string condition, string DateFieldName, string splitStr, DateTime? startDate, DateTime? endDate, string filePath)
        {
            List<string> resultStrs = new List<string>();
            using (StreamReader sr = new StreamReader(filePath, System.Text.Encoding.UTF8))
            {
                String line;
                while ((line = sr.ReadLine()) != null)
                {
                    bool isFit = true;
                    if (!string.IsNullOrWhiteSpace(condition))
                    {
                        isFit = isFit && line.Contains(Convert.ToString(condition));
                    }
                    if (isFit && !string.IsNullOrWhiteSpace(DateFieldName) && !string.IsNullOrWhiteSpace(splitStr) && startDate != null && endDate != null)
                    {
                        string subStr = line.Substring(line.IndexOf(Convert.ToString(DateFieldName) + splitStr) + (Convert.ToString(DateFieldName) + splitStr).Length);
                        DateTime dt = Convert.ToDateTime(subStr.Substring(0, subStr.IndexOf(Convert.ToString(splitStr))));
                        isFit = isFit && dt >= startDate && dt < endDate;
                    }
                    if (isFit)
                    {
                        resultStrs.Add(line);
                    }
                }
            }
            return resultStrs;
        }
        /// <summary>
        /// read notepad file log message
        /// </summary>
        /// <param name="condition">log message condition</param>
        /// <param name="DateFieldName">help to obtain this field value</param>
        /// <param name="splitStr">help to obtain this field value</param>
        /// <param name="startDate">log create start date</param>
        /// <param name="endDate">log create end date</param>
        /// <param name="pageIndex">page index</param>
        /// <param name="pageSize">page size</param>
        /// <param name="filePaths">files path</param>
        /// <param name="totalCount">total log count</param>
        /// <returns></returns>
        public static List<string> LogRead(string condition, string DateFieldName, string splitStr, DateTime? startDate, DateTime? endDate, int pageIndex, int pageSize, List<string> filePaths, out int totalCount)
        {
            List<string> resultStrs = new List<string>();
            String line;
            totalCount = 0;
            foreach (string filePath in filePaths)
            {
                using (StreamReader sr = new StreamReader(filePath, System.Text.Encoding.UTF8))
                {
                    while ((line = sr.ReadLine()) != null)
                    {
                        bool isFit = true;
                        if (!string.IsNullOrWhiteSpace(condition))
                        {
                            isFit = isFit && line.Contains(Convert.ToString(condition));
                        }
                        if (isFit && !string.IsNullOrWhiteSpace(DateFieldName) && !string.IsNullOrWhiteSpace(splitStr) && startDate != null && endDate != null)
                        {
                            string subStr = line.Substring(line.IndexOf(Convert.ToString(DateFieldName) + splitStr) + (Convert.ToString(DateFieldName) + splitStr).Length);
                            DateTime dt = Convert.ToDateTime(subStr.Substring(0, subStr.IndexOf(Convert.ToString(splitStr))));
                            isFit = isFit && dt >= startDate && dt < endDate;
                        }
                        if (isFit)
                        {
                            if (totalCount > (pageIndex - 1) * pageSize && totalCount < pageIndex * pageSize)
                                resultStrs.Add(line);
                            totalCount++;
                        }
                    }
                }
            }
            return resultStrs;
        }
        #endregion

        #region Delete log from notepad file
        public static bool DeleteLogInFile(string condition, string filePath)
        {
            List<string> resultStrs = new List<string>();
            bool isSearch = false;
            using (StreamReader sr = new StreamReader(filePath, System.Text.Encoding.UTF8))
            {
                String line;
                if ((line = sr.ReadLine()) != null)
                {
                    if (line.Contains(condition))
                        isSearch = true;
                    else
                        resultStrs.Add(line);
                }
            }
            if (isSearch)
            {
                File.Delete(filePath);
                using (FileStream fs = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write))
                {
                    using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
                    {
                        foreach (string str in resultStrs)
                        {
                            sw.WriteLine(str);
                        }
                    }
                }
            }
            return isSearch;
        }
        #endregion
    }
}
